
const nsISupports           = Components.interfaces.nsISupports;
const nsICategoryManager    = Components.interfaces.nsICategoryManager;
const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
const nsICommandLine        = Components.interfaces.nsICommandLine;
const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
const nsIFactory            = Components.interfaces.nsIFactory;
const nsIModule             = Components.interfaces.nsIModule;
const nsIWindowWatcher      = Components.interfaces.nsIWindowWatcher;

// configuration
const CHROME_URI = "chrome://widgeon/content/";
const clh_contractID = "@berjon.com/startup-cli/startup;1?type=widgeon";
const clh_CID = Components.ID("{05981AB1-22BA-4399-84C5-DB0D96C451AE}");
const clh_category = "m-widgeon";

/**
 * Opens a chrome window.
 * @param uri a string specifying the URI of the window to open.
 * @param arg an argument to pass to the window (may be null)
 */
function openWindow (uri, arg) {
    var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
                        getService(Components.interfaces.nsIWindowWatcher);
    return ww.openWindow(null, uri, "_blank", "chrome,centerscreen,resizable,dialog=no", arg);
}

/**
 * The XPCOM component that implements nsICommandLineHandler.
 * It also implements nsIFactory to serve as its own singleton factory.
 */
const widgeonHandler = {
    QueryInterface: function clh_QI (iid) {
        if (iid.equals(nsICommandLineHandler) ||
            iid.equals(nsIFactory) ||
            iid.equals(nsISupports)) return this;
        throw Components.results.NS_ERROR_NO_INTERFACE;
    },

    handle: function clh_handle (cmdLine) {
        try {
            var wid = cmdLine.handleFlagWithParam("test", false);
            if (wid) {
                var widFile = cmdLine.resolveFile(wid);
                var file = cmdLine.workingDirectory;
                // XXX hack, may not work everywhere
                widFile.path.split("/").forEach(function (step) { file.append(step); });
                var widget = Components.classes["@berjon.com/widget;1"]
                                       .createInstance()
                                       .wrappedJSObject
                                       .initWithFile(file, "TEST");
                // these values match the test values from the test suite, they're special
                widget.setLocales(['en']);
                widget.supportedFeat["feature:a9bb79c1"] = true;
                // EO test values
                var cfg = widget.config();
                var args = { cfg: cfg };
                args.wrappedJSObject = args;
                var cfgWin = openWindow("chrome://widgeon/content/dump-config.xul", args);
                widget.open();
            }
            else {
                dump("opening the window\n");
                // XXX need to store this window somewhere
                var win = openWindow("chrome://widgeon/content/main.xul", null);
            }
        }
        catch (e) {
            dump("ERROR: " + e + "\n");
            var args = { error: e };
            args.wrappedJSObject = args;
            var cfgWin = openWindow("chrome://widgeon/content/error.xul", args);
            // Components.utils.reportError("incorrect parameter passed to -test on the command line.");
        }
        cmdLine.preventDefault = true;
    },

      // CHANGEME: change the help info as appropriate, but
      // follow the guidelines in nsICommandLineHandler.idl
      // specifically, flag descriptions should start at
      // character 24, and lines should be wrapped at
      // 72 characters with embedded newlines,
      // and finally, the string should end with a newline
      // helpInfo : "  -myapp               Open My Application\n" +
      //            "  -viewapp <uri>       View and edit the URI in My Application,\n" +
      //            "                       wrapping this description\n",
      helpInfo: "  <path-to-widget>      The widget to launch\n",


      createInstance:   function clh_CI (outer, iid) {
          if (outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION;
          return this.QueryInterface(iid);
      },

      lockFactory:  function clh_lock (lock) { /* no-op */ }
};

const widgeonHandlerModule = {
    QueryInterface: function mod_QI (iid) {
        if (iid.equals(nsIModule) || iid.equals(nsISupports)) return this;
        throw Components.results.NS_ERROR_NO_INTERFACE;
    },

    getClassObject: function mod_gch (compMgr, cid, iid) {
        if (cid.equals(clh_CID)) return widgeonHandler.QueryInterface(iid);
        throw Components.results.NS_ERROR_NOT_REGISTERED;
    },

    registerSelf:   function mod_regself (compMgr, fileSpec, location, type) {
        compMgr.QueryInterface(nsIComponentRegistrar);
        compMgr.registerFactoryLocation(clh_CID,
                                        "widgeonHandler",
                                        clh_contractID,
                                        fileSpec,
                                        location,
                                        type);
        var catMan = Components.classes["@mozilla.org/categorymanager;1"].
                                getService(nsICategoryManager);
        catMan.addCategoryEntry("command-line-handler",
                                clh_category,
                                clh_contractID, true, true);
    },

    unregisterSelf: function mod_unreg (compMgr, location, type) {
        compMgr.QueryInterface(nsIComponentRegistrar);
        compMgr.unregisterFactoryLocation(clh_CID, location);
        var catMan = Components.classes["@mozilla.org/categorymanager;1"].
                                getService(nsICategoryManager);
        catMan.deleteCategoryEntry("command-line-handler", clh_category);
    },

    canUnload:  function (compMgr) { return true; }
};

function NSGetModule (comMgr, fileSpec) { return widgeonHandlerModule; }
